<?php

namespace App\Models;

use App\Models\BaseModel;

use SimpleSoftwareIO\QrCode\Generator;
use Illuminate\Filesystem\Filesystem;

use Endroid\QrCode\ErrorCorrectionLevel;
use Endroid\QrCode\LabelAlignment;
use Endroid\QrCode\QrCode;
use Endroid\QrCode\Response\QrCodeResponse;

class Activity extends BaseModel
{
    protected $casts = [
        'created_at' => 'Y-m-d H:i:s',
        'updated_at' => 'Y-m-d H:i:s',
        'start_time' => 'Y-m-d H:i:s',
        'end_time' => 'Y-m-d H:i:s',
    ];

    protected $appends = ['status', 'join_num', 'time'];

    public function getTimeAttribute()
    {
        return [
            0 => $this->attributes['start_time'],
            1 => $this->attributes['end_time'],
        ];
    }

    public function getStatusAttribute()
    {
        if (isset($this->attributes['start_time']) && $this->attributes['start_time'])
        {
            if (time() < strtotime($this->attributes['start_time']))
            {
                $status = 'ready';
            }
            elseif(time() > strtotime($this->attributes['end_time']))
            {
                $status = 'end';
            }
            else
            {
                $status = 'start';
            }

            return $status;
        }

    }

    public function getJoinNumAttribute()
    {
        if (isset($this->attributes['id']))
        {
            $count = ActivityEnter::where('activity_id', $this->attributes['id'])->whereIn('status', ['order','finish'])->count();

            return intval($count);
        }
    }


    protected static function boot()
    {
        parent::boot();
        static::saving(function (Activity $activity) {
            if ($activity->id)
            {
                $store_path = storage_path('app/public/activity/');
                $file = new Filesystem();
                if (!$file->exists($store_path) )
                {
                    $file->makeDirectory($store_path, 0777, true, true);
                }

                $signin_name = $activity->id . '_signin.png';
                $code = env('EASYWECHAT_DELEGATION_HOST').'/pages/auth/signin?activity_id='.$activity->id;
                $qrCode = new QrCode($code);
                $qrCode->setSize(300);
                $qrCode->setWriterByName('png');
                $qrCode->setEncoding('UTF-8');
                $qrCode->setErrorCorrectionLevel(ErrorCorrectionLevel::HIGH());
                $qrCode->setForegroundColor(['r' => 0, 'g' => 0, 'b' => 0, 'a' => 0]);
                $qrCode->setBackgroundColor(['r' => 255, 'g' => 255, 'b' => 255, 'a' => 0]);
                $qrCode->setLogoPath(storage_path('app/public/').$activity->imgurl);
                $qrCode->setLogoSize(80, 80);
                $qrCode->setValidateResult(false);

                $qrCode->setRoundBlockSize(false);
                $qrCode->setMargin(10);
                // $qrCode->setWriterOptions(['exclude_xml_declaration' => true]);
                $qrCode->writeFile($store_path.'/'.$signin_name);

                $signin_qrcode = 'activity/' . $signin_name;

                $activity->signin_qrcode = $signin_qrcode;

                // 生成活动二维码
                $name = $activity->id . '.png';
                $code = env('EASYWECHAT_DELEGATION_HOST').'/pages/activity/detail?id='.$activity->id;
                $qrCode = new QrCode($code);
                $qrCode->setSize(300);
                $qrCode->setWriterByName('png');
                $qrCode->setEncoding('UTF-8');
                $qrCode->setErrorCorrectionLevel(ErrorCorrectionLevel::HIGH());
                $qrCode->setForegroundColor(['r' => 0, 'g' => 0, 'b' => 0, 'a' => 0]);
                $qrCode->setBackgroundColor(['r' => 255, 'g' => 255, 'b' => 255, 'a' => 0]);
                $qrCode->setLogoPath(storage_path('app/public/').$activity->imgurl);
                $qrCode->setLogoSize(80, 80);
                $qrCode->setValidateResult(false);

                $qrCode->setRoundBlockSize(false);
                $qrCode->setMargin(10);
                $qrCode->writeFile($store_path.'/'.$name);

                $qrcode = 'activity/' . $name;
                $activity->qrcode = $qrcode;

            }

        });

        static::created(function (Activity $activity) {
            if ($activity->id)
            {
                // 生成签到码
                $store_path = storage_path('app/public/activity/');
                $file = new Filesystem();
                if (!$file->exists($store_path) )
                {
                    $file->makeDirectory($store_path, 0777, true, true);
                }
                $signin_name = $activity->id . '_signin.png';
                $code = env('EASYWECHAT_DELEGATION_HOST').'/pages/auth/signin?activity_id='.$activity->id;
                // $qrcode = $qrcode->format('png')->size(399)->color(40,40,40)->generate($code, $store_path . $name);

                $qrCode = new QrCode($code);
                $qrCode->setSize(300);
                $qrCode->setWriterByName('png');
                $qrCode->setEncoding('UTF-8');
                $qrCode->setErrorCorrectionLevel(ErrorCorrectionLevel::HIGH());
                $qrCode->setForegroundColor(['r' => 0, 'g' => 0, 'b' => 0, 'a' => 0]);
                $qrCode->setBackgroundColor(['r' => 255, 'g' => 255, 'b' => 255, 'a' => 0]);
                $qrCode->setLogoPath(storage_path('app/public/').$activity->imgurl);
                $qrCode->setLogoSize(80, 80);
                $qrCode->setValidateResult(false);

                $qrCode->setRoundBlockSize(false);
                $qrCode->setMargin(10);
                // $qrCode->setWriterOptions(['exclude_xml_declaration' => true]);
                $qrCode->writeFile($store_path.'/'.$signin_name);

                $signin_qrcode = 'activity/' . $signin_name;

                $activity->signin_qrcode = $signin_qrcode;

                // 生成活动二维码
                $name = $activity->id . '.png';
                $code = env('EASYWECHAT_DELEGATION_HOST').'/pages/activity/detail?id='.$activity->id;
                $qrCode = new QrCode($code);
                $qrCode->setSize(300);
                $qrCode->setWriterByName('png');
                $qrCode->setEncoding('UTF-8');
                $qrCode->setErrorCorrectionLevel(ErrorCorrectionLevel::HIGH());
                $qrCode->setForegroundColor(['r' => 0, 'g' => 0, 'b' => 0, 'a' => 0]);
                $qrCode->setBackgroundColor(['r' => 255, 'g' => 255, 'b' => 255, 'a' => 0]);
                $qrCode->setLogoPath(storage_path('app/public/').$activity->imgurl);
                $qrCode->setLogoSize(80, 80);
                $qrCode->setValidateResult(false);

                $qrCode->setRoundBlockSize(false);
                $qrCode->setMargin(10);
                $qrCode->writeFile($store_path.'/'.$name);
                $qrcode = 'activity/' . $name;
                $activity->qrcode = $qrcode;

                $activity->update();
            }
        });

    }

    public static function getList(array $attributes)
    {
        extract($attributes);

        $where = ['shelves'=>1];

        $model = self::where($where);

        if (!empty($status))
        {
            //判断时间，显示状态
            if(trim($status) == 'ready'){
                $model->where('start_time', '>' ,date("Y-m-d H:i:s", time()));
            }elseif (trim($status) == 'end'){
                $model->where('end_time', '<' , date("Y-m-d H:i:s",time()));
            }elseif (trim($status) == 'start'){
                $model->where('start_time', '<=' , date("Y-m-d H:i:s",time()));
                $model->where('end_time', '>' , date("Y-m-d H:i:s",time()));
            }else{
                $model->where('status', trim($status));
            }

        }

        if (isset($keyword) && trim($keyword))
        {
            $keyword = trim($keyword);
            $keyword = strip_tags($keyword);
            $model->where(function ($query) use ($keyword) {
                $query->where('title', 'like', '%' . strip_tags($keyword) . '%');
            });
        }

        $total = $model->count();

        $model->orderBy('id', 'DESC');

        $member =  \Auth::guard('member')->user();


        if (isset($per_page))
        {
            $data = $model->paginate($per_page)->toArray();

            $result = ['paged' => self::formatPaged($page, $per_page, $total)];
        }
        else
        {
            $data = $model->get()->toArray();

            $result = [];
        }

        foreach ($data['data'] as $k=>$v)
        {
            if (time() < strtotime($v['start_time']))
            {
                $data['data'][$k]['is_appoint'] = 2; //已报名或待签到
                if ($v['apply']==1)
                {
                    $data['data'][$k]['is_appoint'] = 1; //未签到
                }
            }
            elseif(time() > strtotime($v['end_time']))
            {
                $data['data'][$k]['is_appoint'] = 5; //已结束
            }
            else
            {
                $data['data'][$k]['is_appoint'] = 2; //已报名或待签到
                if ($v['apply']==1)
                {
                    $data['data'][$k]['is_appoint'] = 1; //未签到
                }
            }


            if ($member && $data['data'][$k]['is_appoint']!=5)
            {
                $enter = ActivityEnter::where(['member_id' => $member->member_id,'activity_id' => $v['id']])->first();
                if ($enter)
                {
                    if ($enter->status=='order')
                    {
                        $data['data'][$k]['is_appoint'] = 2; //已报名
                    }
                    elseif($enter->status=='cancel')
                    {
                        $data['data'][$k]['is_appoint'] = 2; //已报名或待签到
                        if ($v['apply']==1)
                        {
                            $data['data'][$k]['is_appoint'] = 1; //未签到
                        }
                    }
                    else
                    {
                        $data['data'][$k]['is_appoint'] = 3; //已参与
                    }
                }
            }

            $week = ["周日", "周一", "周二", "周三", "周四", "周五", "周六"];

            $data['data'][$k]['start_time'] = date('m/d ', strtotime($v['start_time'])) . $week[date('w', strtotime($v['start_time']))];
            $data['data'][$k]['end_time'] = date('m/d ', strtotime($v['end_time'])) . $week[date('w', strtotime($v['end_time']))];
        }

        $result['list'] = $data['data'];

        return self::formatBody($result);
    }

    //活动详情Api
    public static function getInfo(array $attributes)
    {
        extract($attributes);

        // $model = Activity::where(['id'=>$activity_id, 'shelves'=>1]);
        $model = Activity::where(['id'=>$activity_id]);

        $activity_data = $model->first();

        if (!$activity_data)
        {
            return self::formatError(404 , '活动不存在或未启用，请联系管理员');
        }

        $activity_data = $activity_data->toArray();

        $member =  \Auth::guard('member')->user();

        if (!$member)
        {
            return self::formatError(400 , '获取用户信息失败');
        }

        if (time() < strtotime($activity_data['start_time']))
        {
            $activity_data['is_appoint'] = 2; //已报名或待签到
            if ($activity_data['apply']==1)
            {
                $activity_data['is_appoint'] = 1; //未签到
            }
        }
        elseif(time() > strtotime($activity_data['end_time']))
        {
            $activity_data['is_appoint'] = 5; //已结束
        }
        else
        {
            $activity_data['is_appoint'] = 2; //已报名或待签到
            if ($activity_data['apply']==1)
            {
                $activity_data['is_appoint'] = 1; //未签到
            }
        }

        $enter = ActivityEnter::where(['member_id' => $member->member_id,'activity_id' => $activity_data['id']])->first();

        if ($enter && $activity_data['is_appoint']!=5)
        {
            if ($enter->status=='order')
            {
                $activity_data['is_appoint'] = 2; //已报名
            }
            elseif($enter->status=='cancel')
            {
                $activity_data['is_appoint'] = 2; //已报名或待签到
                if ($activity_data['apply']==1)
                {
                    $activity_data['is_appoint'] = 1; //未签到
                }
            }
            else
            {
                $activity_data['is_appoint'] = 3; //已参与
            }

            $activity_data['enter'] = $enter->toArray();
        }
        else
        {
            $activity_data['enter'] = [];
        }

        if (!empty($activity_data['start_time']))
        {
            $activity_data['start_time'] = date('Y.m/d H:i', strtotime($activity_data['start_time']));
        }

        if (!empty($activity_data['end_time']))
        {
            $activity_data['end_time'] = date('Y.m/d H:i', strtotime($activity_data['end_time']));
        }

        return self::formatBody(['detail' => $activity_data]);
    }

    // 用户扫码签到
    public static function toSigninFromMember(array $attributes)
    {
        extract($attributes);

        $model = Activity::where([ 'id' => $activity_id, 'shelves'=>1])->first();

        if (!$model)
        {
            return self::formatError(404 , '活动不存在或未启用，请联系管理员');
        }

        if (time() < strtotime($model->start_time))
        {
            return self::formatError(400 , '活动尚未开始');
        }

        if (time() >= strtotime($model->end_time))
        {
            return self::formatError(400 , '活动已结束');
        }

        $member =  \Auth::guard('member')->user();

        if (!$member)
        {
            return self::formatError(404 , '用户不存在');
        }

        if ($model->apply==1)
        {
            $model_enter = ActivityEnter::where('member_id', $member->member_id)->where('activity_id', $model->id)->first();

            if (!$model_enter)
            {
                return self::formatError(400 , '此活动需要先报名');
            }

            if ($model_enter->status=='finish')
            {
                return self::formatError(400 , '您已签到完成，无需签到');
            }

            // 去签到
            $model_enter->status = 'finish';
            $model_enter->source = 'member';
            $model_enter->op_id = $member->member_id;
            $model_enter->save();
        }
        else
        {
            // 无需报名活动签到
            $model_enter = ActivityEnter::where('member_id', $member->member_id)->where('activity_id', $model->id)->first();
            if ($model_enter)
            {
                return self::formatError(400 , '您已签到完成，请勿重复签到');
            }

            // 去签到
            ActivityEnter::create([
                'member_id' => $member->member_id,
                'activity_id' => $activity_id,
                'title' => $model->title,
                'description' => $model->description,
                'score' => $model->score,
                'start_time' => $model->start_time,
                'end_time' => $model->end_time,
                'imgurl' => $model->imgurl,
                'apply' => 0,
                'status' => 'finish',
                'source' => 'member',
                'op_id' => $member->member_id,
                'mobile' => $member->mobile,
            ]);

        }

        // 积分发放
        $current_score = intval($member->score) + intval($model->score);

        Member::where('member_id', $member->member_id)->update([
            'score' => $current_score
        ]);

        // 添加积分日志
        MemberScoreLog::create([
            'member_id' => $member->member_id,
            'action' => 'increase',
            'score' => intval($model->score),
            'current_score' => $current_score,
            'remark' => '活动 ' . $model->title . " 签到发放积分",
        ]);

        return self::formatBody([], '签到成功');
    }

    // 管理员扫描个人码签到
    public static function toSigninFromAdmin(array $attributes)
    {
        extract($attributes);

        $model = Activity::where(['id' => $activity_id, 'shelves'=>1])->first();

        if (!$model)
        {
            return self::formatError(404 , '活动不存在或未启用，请联系管理员');
        }

        if (time() < strtotime($model->start_time))
        {
            return self::formatError(400 , '活动尚未开始');
        }

        if (time() >= strtotime($model->end_time))
        {
            return self::formatError(400 , '活动已结束');
        }

        $user = Member::where('openid', $openid)->first();

        if (!$user)
        {
            return self::formatError(404 , '用户不存在');
        }

        $member_bind = MemberBindAdmin::where('member_id', $user->member_id)->first();

        if ($model->apply==1)
        {
            $model_enter = ActivityEnter::where('member_id', $user->member_id)->where('activity_id', $model->id)->first();

            if (!$model->enter)
            {
                return self::formatError(400 , '此活动需要先报名');
            }

            if ($model->status=='finish')
            {
                return self::formatError(400 , '您已签到完成，请勿重复签到');
            }

            // 去签到
            $model_enter->status = 'finish';
            $model_enter->source = 'admin';
            $model_enter->op_id = $member_bind->admin_id;

            $model_enter->save();
        }
        else
        {
            // 无需报名活动签到
            $model_enter = ActivityEnter::where('member_id', $user->member_id)->where('activity_id', $model->id)->first();
            if ($model_enter)
            {
                return self::formatError(400 , '您已签到完成，请勿重复签到');
            }

            // 去签到
            ActivityEnter::create([
                'member_id' => $user->member_id,
                'activity_id' => $activity_id,
                'title' => $model->title,
                'description' => $model->description,
                'score' => $model->score,
                'start_time' => $model->start_time,
                'end_time' => $model->end_time,
                'imgurl' => $model->imgurl,
                'apply' => 0,
                'status' => 'finish',
                'source' => 'admin',
                'op_id' => $member_bind->admin_id,
                'mobile' => $user->mobile,
            ]);

        }

        // 积分发放
        $current_score = intval($user->score) + intval($model->score);

        Member::where('member_id', $user->member_id)->update([
            'score' => $current_score
        ]);

        // 添加积分日志
        MemberScoreLog::create([
            'member_id' => $user->member_id,
            'action' => 'increase',
            'score' => intval($model->score),
            'current_score' => $current_score,
            'remark' => '活动 ' . $model->title . " 签到发放积分",
        ]);

        return self::formatBody([]);
    }

}
